package com.jamlu.framework.ui.status;

import android.util.Log;

import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.SPUtils;
import com.google.gson.Gson;
import com.jamlu.framework.model.bean.BaseBean;
import com.jamlu.framework.model.bean.BaseListBean;
import com.jamlu.framework.network.ConstantToken;
import com.jamlu.framework.network.NetworkManager;
import com.jamlu.framework.network.NoNetworkException;
import com.jamlu.framework.network.RefreshTokenBean;
import com.jamlu.framework.network.TokenExpiredException;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.annotations.Nullable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by DMing at 2018/2/28 0028
 */
public class RequestUtils {

    public static final int RESPOND_SUCCESS = 0;//响应成功
    public static final int RESPOND_FAILURE = 1;//响应失败
    public static final int TOKEN_EXPIRED = 100;//token过期
    public static final int COUNTRY_ERROR = 10004;//国家省市没有下级

    private IStatus iStatus;
    private Observable observable;


    private RequestUtils(Observable observable) {
        this.observable = observable;
    }

    public static RequestUtils request(@NonNull Observable observable){
        return new RequestUtils(observable);
    }

    public RequestUtils iStatus(@Nullable IStatus iStatus){
        this.iStatus = iStatus;
        return this;
    }

    public Disposable listener(){
        return new WrapRetrofit(iStatus).wrapView(observable, null,null);
    }

    public Disposable listener(Consumer consumer){
        return new WrapRetrofit(iStatus).wrapView(observable, (Consumer<BaseBean>) consumer,null);
    }

    public Disposable listener(Consumer consumer,Consumer<Integer> failureStatus){
        return new WrapRetrofit(iStatus).wrapView(observable, (Consumer<BaseBean>) consumer,failureStatus);
    }

    public Disposable listenerList(){
        return new WrapRetrofit(iStatus).wrapView(observable,null,null);
    }

    public Disposable listenerList(Consumer consumer){
        return new WrapRetrofit(iStatus).wrapView(observable, (Consumer<BaseListBean>) consumer,null);
    }

    public Disposable listenerList(Consumer consumer,Consumer<Integer> failureStatus){
        return new WrapRetrofit(iStatus).wrapView(observable, (Consumer<BaseListBean>) consumer,failureStatus);
    }



    public static class WrapRetrofit {

        private IStatus iStatus;
        private int count;

        WrapRetrofit(IStatus iStatus) {
            count = 0;
            this.iStatus = iStatus;
        }

        <T extends BaseBean> Disposable wrapView(final Observable<T> observable, final Consumer<T> consumer, final Consumer<Integer> failureStatus){
            return observable
            .flatMap(new Function<T, ObservableSource<T>>() {
                @Override
                public ObservableSource<T> apply(T t) throws Exception {
                    if (t.getHttpCode() == TOKEN_EXPIRED){
                        return Observable.error(new TokenExpiredException());
                    }else {
                        return Observable.just(t);
                    }
                }
            })
            .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {  //必定token过期才进入
                @Override
                public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
                    return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                        @Override
                        public ObservableSource<?> apply(Throwable throwable) throws Exception {
                            if (throwable instanceof TokenExpiredException) {
                                ///////////////////////////////////////////刷新
                                RequestBody requestBody = new FormBody.Builder().add("refresh_token", SPUtils.getInstance(ConstantToken.TOKEN).getString(ConstantToken.REFRESH)).build();
                                Request request = new Request.Builder()
                                        .url("http://cke.thgo8.com/?g=Api&c=Users&a=refresh_token")
                                        .post(requestBody)
                                        .build();
                                Call call = NetworkManager.getOkHttpClient().newCall(request);
                                Response response = call.execute();
                                Gson gson = new Gson();
                                RefreshTokenBean refreshTokenBean = gson.fromJson(response.body().string(), RefreshTokenBean.class);
                                response.close();
                                if (refreshTokenBean.getErrno() == 0) { //刷新token成功
                                    SPUtils.getInstance(ConstantToken.TOKEN).put(ConstantToken.REFRESH, refreshTokenBean.getRefresh_token());
                                    SPUtils.getInstance(ConstantToken.TOKEN).put(ConstantToken.ACCESS, refreshTokenBean.getAccess_token());
                                } else { //刷新token 30天已经过期
                                    return Observable.error(new TokenExpiredException());
                                }
                                ///////////////////////////////////////////
                                if (count < 3) {
                                    count++;
                                    return Observable.just(1); //token刷新成功
                                } else {
                                    return Observable.error(new TokenExpiredException());//防止服务器出错的情形,防止死循环
                                }
                            }else {
                                return Observable.error(throwable);
                            }
                        }
                    });
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<T>() {
                @Override
                public void accept(T t) throws Exception {
                    if (t.getHttpCode() == RESPOND_SUCCESS){
                        if (iStatus != null) {
                            if (t instanceof BaseListBean){
                                BaseListBean baseListBean = (BaseListBean)t;
                                iStatus.switchStatus(t.isNothing()?IStatus.NOTHING:IStatus.SUCCESS, baseListBean.getList());//List空数据与有数据,都进入
                            }else {
                                iStatus.switchStatus(t.isNothing()?IStatus.NOTHING:IStatus.SUCCESS);
                            }
                        }
                        if (consumer != null)consumer.accept(t);
                    }else if (t.getHttpCode() == RESPOND_FAILURE){
                        if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_RESPOND,t.getMsg());
                        if (failureStatus != null)failureStatus.accept(IStatus.ERROR_RESPOND);
                    }else if (t.getHttpCode() == COUNTRY_ERROR){
                        if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_RESPOND,t.getMsg());
                        if (failureStatus != null)failureStatus.accept(IStatus.ERROR_COUNTRY);
                    }else {
                        if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_NETWORK);
                        if (failureStatus != null)failureStatus.accept(IStatus.ERROR_NETWORK);
                    }
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    Log.e("request","Status --> Throwable: "+throwable.getMessage());
                    if (throwable instanceof NoNetworkException){
                        if (iStatus != null)iStatus.switchStatus(IStatus.NO_NETWORK);
                        if (failureStatus != null)failureStatus.accept(IStatus.NO_NETWORK);
                    }else if (throwable instanceof TokenExpiredException){
                        if (iStatus != null)iStatus.switchStatus(IStatus.TOKEN_EXPIRED);
                        ActivityUtils.startActivity("com.pts.changex","com.pts.changex.ui.activity.StartActivity");
                    }else {
                        if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_NETWORK);
                        if (failureStatus != null)failureStatus.accept(IStatus.ERROR_NETWORK);
                    }
                }
            });

        }


//        private <T extends BaseBean> void eee(Observable<T> observable,final Consumer<T> consumer, final Consumer<Integer> failureStatus){
//            return observable
//                    .flatMap(new Function<T, ObservableSource<T>>() {
//                        @Override
//                        public ObservableSource<T> apply(T t) throws Exception {
//                            if (t.getHttpCode() == TOKEN_EXPIRED){
//                                Log.i("pts","token expired error<----");
//                                return Observable.error(new IllegalStateException("token expired error"));
//                            }else {
//                                return Observable.just(t);
//                            }
//                        }
//                    })
//                    .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {  //必定token过期才进入
//                        @Override
//                        public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
//                            return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
//                                @Override
//                                public ObservableSource<?> apply(Throwable throwable) throws Exception {
//                                    if (count < 3) {
//                                        count++;
//                                        Log.i("pts","token expired error: "+count);
//                                        return Observable.just(1);
//                                    }else {
//                                        return Observable.error(new IllegalStateException("token request error"));
//                                    }
//                                }
//                            });
//                        }
//                    })
//                    .subscribeOn(Schedulers.io())
//                    .observeOn(AndroidSchedulers.mainThread())
//                    .subscribe(new Consumer<T>() {
//                        @Override
//                        public void accept(T t) throws Exception {
//                            Log.i("pts","token!!!!!!!!!!!!");
//                            if (t.getHttpCode() == RESPOND_SUCCESS){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.SUCCESS);
//                                if (consumer != null)consumer.accept(t);
//                            }else if (t.getHttpCode() == RESPOND_FAILURE){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_RESPOND,t.getMsg());
//                                if (failureStatus != null)failureStatus.accept(IStatus.ERROR_RESPOND);
//                            }else if (t.getHttpCode() == TOKEN_EXPIRED){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_RESPOND,t.getMsg());
////                        ActivityUtils.finishAllActivities(); //关闭所有页面
//                            }else if (t.getHttpCode() == COUNTRY_ERROR){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_RESPOND,t.getMsg());
//                                if (failureStatus != null)failureStatus.accept(IStatus.ERROR_COUNTRY);
//                            }else {
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_NETWORK);
//                                if (failureStatus != null)failureStatus.accept(IStatus.ERROR_NETWORK);
//                            }
//                        }
//                    }, new Consumer<Throwable>() {
//                        @Override
//                        public void accept(Throwable throwable) throws Exception {
//                            Log.i("pts","token expired error!!!!!!!!!!!!");
//                            if (throwable instanceof NoNetworkException){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.NO_NETWORK);
//                                if (failureStatus != null)failureStatus.accept(IStatus.NO_NETWORK);
//                            }else {
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_NETWORK);
//                                if (failureStatus != null)failureStatus.accept(IStatus.ERROR_NETWORK);
//                            }
//                        }
//                    });
//        }

//        <T extends BaseListBean> Disposable wrapRvView(Observable<T> observable, final Consumer<T> consumer,final Consumer<Integer> failureStatus){
//            return observable.subscribeOn(Schedulers.io())
//                    .observeOn(AndroidSchedulers.mainThread())
//                    .subscribe(new Consumer<T>() {
//                        @Override
//                        public void accept(T t) throws Exception {
//                            if (t.getHttpCode() == RESPOND_SUCCESS){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.SUCCESS, t.getList());//List空数据与有数据,都进入
//                                if (consumer != null)consumer.accept(t);
//                            }else if (t.getHttpCode() == RESPOND_FAILURE){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_RESPOND,t.getMsg());
//                                if (failureStatus != null)failureStatus.accept(IStatus.ERROR_RESPOND);
//                            }else if (t.getHttpCode() == TOKEN_EXPIRED){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_RESPOND,t.getMsg());
//                                ActivityUtils.finishAllActivities(); //关闭所有页面
//                            }else {
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_NETWORK);
//                                if (failureStatus != null)failureStatus.accept(IStatus.ERROR_NETWORK);
//                            }
//                        }
//                    }, new Consumer<Throwable>() {
//                        @Override
//                        public void accept(Throwable throwable) throws Exception {
//                            if (throwable instanceof NoNetworkException){
//                                if (iStatus != null)iStatus.switchStatus(IStatus.NO_NETWORK);
//                                if (failureStatus != null)failureStatus.accept(IStatus.ERROR_NETWORK);
//                            }else {
//                                if (iStatus != null)iStatus.switchStatus(IStatus.ERROR_NETWORK);
//                                if (failureStatus != null)failureStatus.accept(IStatus.ERROR_NETWORK);
//                            }
//                        }
//                    });
//        }
    }



}
